package com.example.netty.server.tcp;

import com.example.netty.service.CallBack;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.BlockingQueue;

public class TcpServerHandler extends ChannelInboundHandlerAdapter {

    private final static Logger logger = LoggerFactory.getLogger(TcpServer.class);

    private final BlockingQueue<ChannelHandlerContext> queue;

    private final CallBack callBack;

    public TcpServerHandler(BlockingQueue<ChannelHandlerContext> queue, CallBack callBack) {
        this.queue = queue;
        this.callBack = callBack;
    }


    /**
     * 注册连接
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        logger.info(">>>>>>>CHANNEL【{}:{}】创建连接", ctx.channel().id(), ctx.channel().remoteAddress());
        if (!queue.offer(ctx)) {
            ChannelHandlerContext context = queue.poll();
            if (context != null) {
                context.close();
            }
            queue.offer(ctx);
        }
    }

    /**
     * 断开连接
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        logger.info(">>>>>>>CHANNEL【{}:{}】断开连接", ctx.channel().id(), ctx.channel().remoteAddress());
        queue.remove(ctx);
    }


    /**
     * 接收消息
     *
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        logger.info(">>>>>>>CHANNEL【{}:{}】接收到消息：{}", ctx.channel().id(), ctx.channel().remoteAddress(),msg.toString());
        callBack.response(ctx,msg);
    }


    /**
     * 异常处理
     *
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        logger.info(">>>>>>>CHANNEL【{}:{}】出现异常：{}", ctx.channel().id(), ctx.channel().remoteAddress(),cause.getMessage());
        queue.remove(ctx);
    }
}
